package boardgamer.yavalath.client.threads;

import boardgamer.common.GameUpdate;
import boardgamer.common.client.Logger;
import boardgamer.common.net.PlayerId;
import boardgamer.yavalath.common.GeneratesMove;
import boardgamer.yavalath.common.YavalathGameServer;
import boardgamer.yavalath.common.YavalathGameState;
import boardgamer.yavalath.common.YavalathGameStateChange;
import boardgamer.yavalath.common.YavalathTile;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * AIThread running on local client. Doesn't really have to be a seperate thread.
 */
public class AiThread implements Runnable {

  private PlayerId playerId;
  private YavalathGameServer yavalathGameServer;
  private GeneratesMove generatesMove;

  public AiThread(PlayerId playerId, YavalathGameServer yavalathGameServer, GeneratesMove generatesMove) {
    this.playerId = checkNotNull(playerId, "playerId");
    this.yavalathGameServer = checkNotNull(yavalathGameServer, "yavalathGameServer");
    this.generatesMove = checkNotNull(generatesMove, "generatesMove");
  }

  @Override
  public void run() {
    int lastUpdate = 0;
    while(true) {
      ImmutableList<GameUpdate<YavalathGameState, YavalathGameStateChange>> updates = null;
      
      try {
        updates = yavalathGameServer.refresh(lastUpdate);
        if (updates != null && !updates.isEmpty()
            && Iterables.getLast(updates).getEndState().getCurrentPlayer().equals(playerId)) {
          Thread.sleep(1000);
          YavalathGameState lastGameState = Iterables.getLast(updates).getEndState();

          Logger.log(10, "Calculating move.");
          YavalathTile tile = generatesMove.getMove(lastGameState);
          Logger.log(10, "Finished calculating move.");
          yavalathGameServer.addToken(playerId, tile.getX(), tile.getY());
        }
      } catch (Exception e) {
        Logger.log(7, "AiThread: exception getting updates " + e.toString() + e.getMessage() + e.getCause().getMessage());
      }

      lastUpdate += updates.size();
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
       // meh
      }
    }
  }
}
